#!/bin/sh

. "$SPEC_PATH/abstract/dbops-pgbench"

e2e_test_extra_hash() {
  "$SHELL" "$PROJECT_PATH/stackgres-k8s/ci/build/build-functions.sh" path_hash \
    "$(realpath --relative-to "$PROJECT_PATH" "$SPEC_PATH/abstract/dbops-pgbench")"
}

e2e_test_install() {
  DBOPS_NAME=pgbench

  create_or_replace_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE" 2

  wait_pods_running "$CLUSTER_NAMESPACE" 2
  wait_cluster "$CLUSTER_NAME" "$CLUSTER_NAMESPACE"
}

e2e_test() {
  run_test "Checking that pgbench is working" check_pgbench_is_working

  run_test "Checking that pgbench is working with 10 clients and threads" check_pgbench_many_is_working

  run_test "Checking that pgbench is working with prepared statements" check_pgbench_prepared_is_working

  run_test "Checking that pgbench is working for replicas" check_pgbench_replicas_is_working

  run_test "Checking that pgbench timeout works correctly" check_pgbench_timed_out
}

check_pgbench_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: benchmark
  benchmark:
    type: pgbench
    pgbench:
      databaseSize: 100Mi
      duration: PT10S
EOF

  wait_until eval '[ "$(kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" \
    --template "{{ .status.opRetries }}")" = "0" ]'
  kubectl get sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME" -o yaml > "$LOG_PATH/sgdbops.yaml"
  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
  kubectl create -f "$LOG_PATH/sgdbops.yaml"

  check_pgbench

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_pgbench_many_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: benchmark
  benchmark:
    type: pgbench
    pgbench:
      databaseSize: 100Mi
      duration: PT10S
      concurrentClients: 10
      threads: 10
EOF

  check_pgbench

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_pgbench_prepared_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: benchmark
  benchmark:
    type: pgbench
    pgbench:
      databaseSize: 100Mi
      duration: PT10S
      usePreparedStatements: true
EOF

  check_pgbench

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_pgbench_replicas_is_working() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: benchmark
  benchmark:
    type: pgbench
    pgbench:
      databaseSize: 100Mi
      duration: PT10S
    connectionType: replicas-service
EOF

  check_pgbench

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"
}

check_pgbench_timed_out() {
  cat << EOF | kubectl create -f -
apiVersion: stackgres.io/v1
kind: SGDbOps
metadata:
  name: $DBOPS_NAME
  namespace: $CLUSTER_NAMESPACE
spec:
  sgCluster: $CLUSTER_NAME
  op: benchmark
  timeout: PT1S
  benchmark:
    type: pgbench
    pgbench:
      databaseSize: 100Mi
      duration: PT10S
EOF

  if kubectl wait --timeout "${E2E_TIMEOUT}s" -n "$CLUSTER_NAMESPACE" sgdbops "$DBOPS_NAME" \
    --for condition=Completed \
    && kubectl wait --timeout "0s" -n "$CLUSTER_NAMESPACE" sgdbops "$DBOPS_NAME" \
    --for condition=Failed
  then
    success "pgbench failed."
  else
    fail "pgbench did not fail."
  fi

  if [ "$(kubectl get -n "$CLUSTER_NAMESPACE" job \
    -l "stackgres.io/dbops-name=$DBOPS_NAME,stackgres.io/db-ops=true" \
    -o name 2>/dev/null | wc -l)" = 1 ]
  then
    success "pgbench job was not removed after failure."
  else
    fail "pgbench job was removed after failure."
  fi

  kubectl delete sgdbops -n "$CLUSTER_NAMESPACE" "$DBOPS_NAME"

  if wait_until eval '[ "$(kubectl get -n "$CLUSTER_NAMESPACE" job \
    -l "stackgres.io/dbops-name=$DBOPS_NAME,stackgres.io/db-ops=true" \
    -o name 2>/dev/null | wc -l)" = 0 ]'
  then
    success "pgbench job was removed after sgdbops was removed."
  else
    fail "pgbench job was not removed after sgdbops was removed."
  fi
}
